#pragma once

#include "MBLabel.h"
#include "MBCameraViewFrustum.h"
#include "MBVec3.h"
#include "MBMatrix3x3.h"

/**
  *	An MBCameraView object belongs to one particular image. It has a unique
  * ID and was taken with a camera, whose exact parameters are known. Those
  * parameters are the intrinsic and internal calibration parameters, as well
  * as the position and orientation during the exposure of the image.
  */
class MBCameraView : public MBLabel
{
public:
	MBCameraView(	const std::string &imagePath,
					const MBCameraModel *cameraModel,
					const MBuint &cameraPosID,
					const MBMatrix4x4 &mount,
					const MBMatrix4x4 &COP,
					const MBMatrix4x4 &SOP,
					const MBMatrix4x4 &POP = MBMatrix4x4( 1.0 ),
					const double usedImageAreaRadius = -1.0 );
	MBCameraView(	const std::string &imagePath,
					const MBCameraModel *cameraModel,
					const MBuint &cameraPosID,
					const double &locationX,
					const double &locationY,
					const double &locationZ,
					const MBMatrix3x3 &rotationMatrix,
					const double usedImageAreaRadius = -1.0 );
	MBCameraView(	const std::string &imagePath,
					const MBCameraModel *cameraModel,
					const MBuint &cameraPosID,
					const double &locationX,
					const double &locationY,
					const double &locationZ,
					const double &rotationX,
					const double &rotationY,
					const double &rotationZ,
					const double usedImageAreaRadius = -1.0 );

	virtual const MBCameraModel *GetCameraModel( void ) const;
	const MBuint &GetCameraPosID( void ) const;
	virtual const std::string &GetImagePath( void ) const;
	virtual const MBVec3 &GetPosition( void ) const;
	virtual const MBVec2 &GetTexcoordShiftVector( void ) const;
	virtual const std::string &GetUndistortedImagePath( void ) const;
	const double &GetUsedImageAreaRadius( void ) const;
	const MBCameraViewFrustum &GetViewFrustum( void ) const;
	virtual const MBMatrix4x4 &GetWorldSpaceToViewSpaceTransformation( void ) const;

	const MBVec3 &GetWorldSpaceToViewSpaceRotationVector( void ) const;
	const MBVec3 &GetWorldSpaceToViewSpaceTranslationVector( void ) const;

	void SetUndistortedImagePath( const std::string &undistortedImagePath );

	void SetMaskPath( const std::string &maskPath );
	virtual const std::string &GetMaskPath( void ) const;

private:
	/** full path of the image, the camera view belongs to */
	std::string mImagePath;
	/** full path of the undistorted version of the image, the camera view belongs to */
	std::string mUndistortedImagePath;
	/** const pointer to the underlying camera model */
	const MBCameraModel *mCameraModel;
	/** 4x4 matrix describing the world space to view space transformation */
	MBMatrix4x4 mWorldSpaceToViewSpaceTransformation;
	/** 3D rotation vector of the world space to view space transformation */
	MBVec3 mWorldSpaceToViewSpaceRotationVector;
	/** 3D translation vector of the world space to view space transformation */
	MBVec3 mWorldSpaceToViewSpaceTranslationVector;
	/** position of the camera in 3D space during exposure of the image */
	MBVec3 mPosition;
	/** unique ID of the camera position */
	MBuint mCameraPosID;
	/** View Frustum of the camera */
	MBCameraViewFrustum mViewFrustum;
	/** Radius of effectively used image area, 1.0 is the distance from the midpoint to the top (or bottom) of the image */
	double mUsedImageAreaRadius;
	/** shift vector in the UV-space to compensate the registration errors, always (0.0, 0.0) for MBCameraView objects */
	static MBVec2 cameraViewShiftVector;
	/** full path of the image mask */
	std::string mMaskPath;
};